import logging

# from transitions import Machine
import os
import time
import traceback

from src.common.prj_path import get_abs_path
from src.common.utils import read_yaml
from src.transition.model import MyMatter

if os.name == 'nt':
    from transitions.extensions import HierarchicalGraphMachine as Machine
else:
    from transitions.extensions import HierarchicalMachine as Machine

LOG = logging.getLogger()


class TransitionFsm(object):
    def __init__(self, parse_fsm_object_list):
        self.model = MyMatter(parse_fsm_object_list)
        config = read_yaml(get_abs_path('settings', 'fsm.yaml'))
        config = self.del_graph_param(config)
        config['model'] = self.model
        self.machine = Machine(**config)
        self.model.show_graph()

    def del_graph_param(self, config):
        key_list = ['title', 'show_conditions', 'show_auto_transitions', 'show_state_attributes']
        for key in key_list:
            if key in config:
                del config[key]
        return config

    def exception_flag(self):
        pass

    def run(self):
        while True:
            try:
                now_state = self.model.state
                triggers = self.machine.get_triggers(now_state)
                self.machine.get_triggers()
                triggers = [trigger for trigger in triggers if not trigger.startswith('to_')]
                print(triggers)
                for trigger in triggers:
                    if self.model.trigger(trigger):
                        break
                    else:
                        LOG.warning('not {}, try another'.format(trigger))
                else:
                    raise Exception('无法从{}进行状态迁移'.format(now_state))
            except Exception as e:
                LOG.error('出现异常，当前步骤为={},err={}'.format(self.model.state, repr(e)))
                self.machine.set_state('Exception', self.model)
                LOG.info('重新设置当前起点为={}'.format(self.model.state))
                time.sleep(1)
            else:
                LOG.debug('成功从{}执行状态迁移函数{}'.format(now_state, trigger))


if __name__ == '__main__':
    a = TransitionFsm(1)
    a.run()
